<?php
namespace app\data_magic\data;

use think\Db;
use app\data_magic\struct\Option;
use app\data_magic\struct\Reference;
use app\data_magic\struct\Location;
use app\data_magic\struct\File;
use app\data_magic\extension\StringParams;


/**
 * 字段数据
 * @property string $id 字段ID
 * @property string $table_id 表ID
 * @property string $name 字段名称
 * @property string $alias 别名
 * @property string $title 标题
 * @property string $describe 描述
 * @property string $data_type SQL类型
 * @property string $max_length 最大长度
 * @property string $type 类型
 * @property string $type_params 类型相关的参数
 * @property string $create_time 创建时间
 * @property string $update_time 更新时间
 * @property string $is_nullable 是否可以为空
 */
class Field extends DataRow
{
    /**
     * @var bool $readable 是否可读
     * @var bool $writable 是否可写
     * @var bool $required 是否必填
     */
    public $readable=true;
    public $writable=true;
    public $required=false;

    /**
     * 从数据库加载字段列表
     * @param string $table_id 表ID
     * @return self[]
     */
    static public function loadFieldList($table_id)
    {
        $list=Db::table("dm_field")->where(["table_id"=>$table_id])->select();
        if(!$list){
            return [];
        }
        $fields=[];
        foreach($list as $item){
            $fields[]=new self($item);
        }
        return $fields;
    }
    /**
     * 字段参数
     * @var Option[] $options 选择类型的字段中的选项
     * @var Reference $refer 引用类型的字段的参数
     */
    public $options=[];
    public $refer=null;
    /**
     * 解析字段参数
     * @param self[] $fields 字段列表
     * @return self[]
     */
    static public function parserFieldParams($fields)
    {
        foreach($fields as $field){
            if(in_array($field->type,["select","radio","checkbox"])){
                $options=StringParams::option($field->type_params);
                $field->options=[];
                foreach($options as $name => $title){
                    $option=new Option();
                    $option->name=$name;
                    $option->title=$title;
                    $field->options[]=$option;
                }
            }
            elseif(in_array($field->type,["refer"])){
                $params=StringParams::assoc(["table_name","action_id","id_field","name_field"],$field->type_params);
                $refer=new Reference();
                $refer->table_name=$params["table_name"];
                $refer->action_id=$params["table_name"];
                $refer->id_field=$params["id_field"];
                $refer->name_field=$params["name_field"];
                $field->refer=$refer;
            }
        }
        return $fields;
    }
    /**
     * 将存储格式的数据转换为内部类型的数据
     * @param self[] $fields 字段列表
     * @param string[] $item 数据(关联数组)
     * @return mixed[]
     */
    static public function convertFromStorageFormat($fields,$item)
    {
        $result=[];
        foreach($fields as $field){
            if(isset($item[$field->name])){
                if(in_array($field->type,["select","radio","checkbox","refer"])){
                    $result[$field->name]=explode(",",$item[$field->name]);
                }
                elseif(in_array($field->type,["images","files"])){
                    $files=[];
                    if($item[$field->name]){
                        $file_list=json_decode($item[$field->name],true);
                        foreach($file_list as $file_item){
                            $file=new File();
                            $file->name=$file_item["name"];
                            $file->url=$file_item["url"];
                            $files[]=$file;
                        }
                    }
                    $result[$field->name]=$files;
                }
                elseif($field->type==="location"){
                    $location=new Location();
                    if($item[$field->name]){
                        $map=json_decode($item[$field->name],true);
                        $location->text=$map["text"];
                        $location->longitude=$map["longitude"];
                        $location->latitude=$map["latitude"];
                    }
                    $result[$field->name]=$location;
                }
                else{
                    $result[$field->name]=$item[$field->name];
                }
            }
        }
        return $result;
    }
    /**
     * 将内部类型的数据转换成存储格式的数据
     * @param self[] $fields 字段列表
     * @param mixed[] $item 数据(关联数组)
     * @return string[]
     */
    static public function convertToStorageFormat($fields,$item)
    {
        $result=[];
        foreach($fields as $field){
            if(isset($item[$field->name])){
                if(in_array($field->type,["select","radio","checkbox","refer"])){
                    $result[$field->name]=implode(",",$item[$field->name]);
                }
                elseif(in_array($field->type,["images","files"])){
                    /** @var File $file */
                    $file_list=[];
                    foreach($item[$field->name] as $file){
                        $file_list[]=[
                            "name"=>$file->name,
                            "url"=>$file->url,
                        ];
                    }
                    $result[$field->name]=json_encode($file_list);
                }
                elseif($field->type==="location"){
                    /** @var Location $location */
                    $location=$item[$field->name];
                    $map=[
                        "text"=>$location->text,
                        "longitude"=>$location->longitude,
                        "latitude"=>$location->latitude,
                    ];
                    $result[$field->name]=json_encode($map);
                }
                else{
                    $result[$field->name]=$item[$field->name];
                }
            }
        }
        return $result;
    }
}
